home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / class / link.d < prev    next >
Text File  |  1996-08-25  |  5KB  |  283 lines

  1.  
  2. /*
  3.  *
  4.  *    Copyright (c) 1993-1996 Algorithms Corporation
  5.  *    3020 Liberty Hills Drive
  6.  *    Franklin, TN  37067
  7.  *
  8.  *    ALL RIGHTS RESERVED.
  9.  *
  10.  *
  11.  *
  12.  */
  13.  
  14.  
  15.  
  16. defclass  Link  {
  17.     iPrev;        /*  previous link            */
  18.     iNext;        /*  next link                */
  19.     iList;        /*  list where link is a member        */
  20. };
  21.  
  22.  
  23.  
  24. imeth    gNext()
  25. {
  26.     return iNext == iList ? NULLOBJ : iNext;
  27. }
  28.  
  29. imeth    gPrevious()
  30. {
  31.     return iPrev == iList ? NULLOBJ : iPrev;
  32. }
  33.  
  34. imeth    gList()
  35. {
  36.     return iList;
  37. }
  38.  
  39. imeth    gChangeNext(next)
  40. {
  41.     ChkArgNul(next, 2);
  42.     iNext = next;
  43.     return self;
  44. }
  45.  
  46. imeth    gChangePrevious(prev)
  47. {
  48.     ChkArgNul(prev, 2);
  49.     iPrev = prev;
  50.     return self;
  51. }
  52.  
  53. imeth    gInitLink(list, prev, next)
  54. {
  55.     ChkArgNul(list, 2);
  56.     ChkArgNul(prev, 3);
  57.     ChkArgNul(next, 4);
  58.     iList = list;
  59.     iPrev = prev;
  60.     iNext = next;
  61.     return self;
  62. }
  63.  
  64. imeth    gRemove : Remove ()
  65. {
  66. #ifdef    NATIVE_THREADS
  67.     if (iList)
  68.         gEnterCriticalSection(iList);
  69. #endif
  70.     if (iNext  &&  iNext != self)
  71.         ivPtr(iNext)->iPrev = iPrev;
  72.     if (iPrev  &&  iPrev != self)
  73.         ivPtr(iPrev)->iNext = iNext;
  74.     if (iList  &&  iList != self)
  75.         gIncNelm(iList, -1);
  76.     iList = iNext = iPrev = NULLOBJ;
  77. #ifdef    NATIVE_THREADS
  78.     if (iList)
  79.         gLeaveCriticalSection(iList);
  80. #endif
  81.     return self;
  82. }
  83.  
  84. imeth    object    gDispose()
  85. {
  86.     Remove(self);
  87.     return gDispose(super);
  88. }
  89.  
  90. imeth    object    gDeepDispose()
  91. {
  92.     Remove(self);
  93.     return gDeepDispose(super);
  94. }
  95.  
  96. /*  link lnk before self    */
  97.  
  98. imeth    gAddBefore : AddBefore (lnk)
  99. {
  100.     ivType    *iv2;
  101.  
  102.     ChkArg(lnk, 2);
  103.     if (self == lnk)
  104.         return self;
  105. #ifdef    NATIVE_THREADS
  106.     if (iList)
  107.         gEnterCriticalSection(iList);
  108. #endif
  109.     iv2 = ivPtr(lnk);
  110.     if (iv2->iList  ||  iv2->iNext  ||  iv2->iPrev)
  111.         gError(self, "Attempt to add a node to a list which is a member of another list.");
  112.     if (iv2->iPrev = iPrev)
  113.         ivPtr(iv2->iPrev)->iNext = lnk;
  114.     iv2->iNext = self;
  115.     iPrev  = lnk;
  116.     if (iv2->iList = iList)
  117.         gIncNelm(iList, 1);
  118. #ifdef    NATIVE_THREADS
  119.     if (iList)
  120.         gLeaveCriticalSection(iList);
  121. #endif
  122.     return self;
  123. }
  124.  
  125. /*  link lnk after self      */
  126.  
  127. imeth    gAddAfter : AddAfter (lnk)
  128. {
  129.     ivType    *iv2;
  130.  
  131.     ChkArg(lnk, 2);
  132.     if (self == lnk)
  133.         return self;
  134. #ifdef    NATIVE_THREADS
  135.     if (iList)
  136.         gEnterCriticalSection(iList);
  137. #endif
  138.     iv2 = ivPtr(lnk);
  139.     if (iv2->iList  ||  iv2->iNext  ||  iv2->iPrev)
  140.         gError(self, "Attempt to add a node to a list which is a member of another list.");
  141.     if (iv2->iNext = iNext)
  142.         ivPtr(iv2->iNext)->iPrev = lnk;
  143.     iv2->iPrev = self;
  144.     iNext  = lnk;
  145.     if (iv2->iList = iList)
  146.         gIncNelm(iList, 1);
  147. #ifdef    NATIVE_THREADS
  148.     if (iList)
  149.         gLeaveCriticalSection(iList);
  150. #endif
  151.     return self;
  152. }
  153.  
  154. /*  move self to the beginning of the list it's on  */
  155.  
  156. imeth    gMoveBeginning()
  157. {
  158.     ivType    *iv2;
  159.  
  160.     if (!iList  ||  self == iList)
  161.         return NULLOBJ;
  162. #ifdef    NATIVE_THREADS
  163.     gEnterCriticalSection(iList);
  164. #endif
  165.     iv2 = ivPtr(iList);
  166.     if (iv2->iNext == self) {
  167. #ifdef    NATIVE_THREADS
  168.         gLeaveCriticalSection(iList);
  169. #endif
  170.         return self;    /*  already at head  */
  171.     }
  172.     Remove(self);
  173.     AddAfter(iList, self);
  174. #ifdef    NATIVE_THREADS
  175.     gLeaveCriticalSection(iList);
  176. #endif
  177.     return self;
  178. }
  179.  
  180. /*  move self to the end of the list it's on  */
  181.  
  182. imeth    gMoveEnd()
  183. {
  184.     ivType    *iv2;
  185.  
  186.     if (!iList  ||  self == iList)
  187.         return NULLOBJ;
  188. #ifdef    NATIVE_THREADS
  189.     gEnterCriticalSection(iList);
  190. #endif
  191.     iv2 = ivPtr(iList);
  192.     if (iv2->iPrev == self) {
  193. #ifdef    NATIVE_THREADS
  194.         gLeaveCriticalSection(iList);
  195. #endif
  196.         return self;    /*  already at end  */
  197.     }
  198.     Remove(self);
  199.     AddBefore(iList, self);
  200. #ifdef    NATIVE_THREADS
  201.     gLeaveCriticalSection(iList);
  202. #endif
  203.     return self;
  204. }
  205.  
  206. /*  move self after lnk  */
  207.  
  208. imeth    gMoveAfter(lnk)
  209. {
  210.     ChkArg(lnk, 2);
  211.     Remove(self);
  212.     AddAfter(lnk, self);
  213.     return self;
  214. }
  215.  
  216. /*  move self before lnk  */
  217.  
  218. imeth    gMoveBefore(lnk)
  219. {
  220.     ChkArg(lnk, 2);
  221.     Remove(self);
  222.     AddBefore(lnk, self);
  223.     return self;
  224. }
  225.  
  226. imeth    gStringRepValue()
  227. {
  228.     if (iList  &&  iList == self)
  229.         return gStringRepValue(super);
  230.     else
  231.         return vSprintf(String, "(<%8.8lx>, <%8.8lx>)", iPrev, iNext);
  232. }
  233.  
  234. imeth    gStringRep()
  235. {
  236.     object    s, t;
  237.  
  238.     s = gStringRep(super);
  239.     t = gStringRepValue(self);
  240.     vBuild(s, NULL, t, "\n", NULL);
  241.     gDispose(t);
  242.     return s;
  243. }
  244.  
  245. imeth    gCopy, gDeepCopy ()
  246. {
  247.     object    nobj;
  248.     ivType    *iv2;
  249.  
  250.     nobj = gCopy(super);
  251.     iv2 = ivPtr(nobj);
  252.     iv2->iList = iv2->iNext = iv2->iPrev = NULLOBJ;
  253.     return nobj;
  254. }
  255.  
  256. imeth    gNth(int idx)
  257. {
  258.     while (idx > 0  &&  self)  {
  259.         self = gNext(self);
  260.         idx--;
  261.     }
  262.     while (idx < 0  &&  self)  {
  263.         self = gPrevious(self);
  264.         idx++;
  265.     }
  266.     return idx ? NULLOBJ : self;
  267. }
  268.  
  269.  
  270.  
  271.  
  272. /*
  273.  *
  274.  *    Copyright (c) 1993-1996 Algorithms Corporation
  275.  *    3020 Liberty Hills Drive
  276.  *    Franklin, TN  37067
  277.  *
  278.  *    ALL RIGHTS RESERVED.
  279.  *
  280.  *
  281.  *
  282.  */
  283.